package demo8

import (
	"fmt"
	"net/http"
	"sync"
)

/*
	等待组（sync.WaitGroup）
	1. 我们可以使用方法调用 wg.Add(delta) 来改变值 wg 维护的计数。
	2. 方法调用 wg.Done() 和 wg.Add(-1) 是完全等价的。
	3. 如果一个 wg.Add(delta) 或者 wg.Done() 调用将 wg 维护的计数更改成一个负数，一个恐慌将产生。
	4. 当一个协程调用了 wg.Wait() 时，
		4.1 如果此时 wg 维护的计数为零，则此 wg.Wait() 此操作为一个空操作（noop）；
		4.2 否则（计数为一个正整数），此协程将进入阻塞状态。当以后其它某个协程将此计数更改至 0 时（一般通过调用 wg.Done()），
			此协程将重新进入运行状态（即 wg.Wait() 将返回）。
*/

// TestDemo817 等待组（sync.WaitGroup）
func TestDemo817() {
	// 声明一个等待组
	var wg sync.WaitGroup

	// 准备一系列的网站地址
	var urls = []string{
		"http://www.github.com/",
		"https://www.qiniu.com/",
		"https://www.golangtc.com/",
	}

	// 遍历地址
	for _, url := range urls {
		// 每一个任务开始时，将等待组增加1
		wg.Add(1)

		// 开启一个并发
		go func(url string) {
			// 使用 defer, 表示函数完成时将等待组值减一
			defer wg.Done()

			// 使用 http 访问提供的地址
			_, err := http.Get(url)

			// 访问完成后，打印地址和可能发生的错误
			fmt.Println(url, err)

			// 通过参数传递 url 地址
		}(url)

		// 等待所有的任务完成
		wg.Wait()

		fmt.Println("over")
	}
}
